/**
 * @file bmi088.h
 * @brief BMI088 IMU驱动 - H743-V2飞控板
 * @author Flight Control Team
 * @date 2025-11-09
 *
 * BMI088是Bosch的6轴IMU，包含3轴加速度计和3轴陀螺仪
 *
 * 硬件连接（参考 reference_firmware/h743_v2_pin_analysis.md）:
 *   - SPI2总线
 *   - CS_ACCEL: PD4 (加速度计片选)
 *   - CS_GYRO:  PD5 (陀螺仪片选)
 *   - DRDY_ACCEL: PC14 (加速度计数据就绪)
 *   - DRDY_GYRO:  PC15 (陀螺仪数据就绪)
 *
 * 配置:
 *   - 加速度计: ±24g, 1600Hz, Normal滤波
 *   - 陀螺仪: ±2000dps, 2000Hz, Normal滤波
 *   - SPI模式: Mode 3 (CPOL=1, CPHA=1)
 *   - 最大SPI时钟: 10MHz
 */

#ifndef __BMI088_H
#define __BMI088_H

#ifdef __cplusplus
extern "C" {
#endif

#include <stdint.h>

/* ========== 加速度计寄存器定义 ========== */
#define BMI088_ACC_CHIP_ID          0x00  /* 芯片ID寄存器 (固定值: 0x1E) */
#define BMI088_ACC_ERR_REG          0x02  /* 错误寄存器 */
#define BMI088_ACC_STATUS           0x03  /* 状态寄存器 */
#define BMI088_ACC_X_LSB            0x12  /* X轴加速度低字节 */
#define BMI088_ACC_X_MSB            0x13  /* X轴加速度高字节 */
#define BMI088_ACC_Y_LSB            0x14  /* Y轴加速度低字节 */
#define BMI088_ACC_Y_MSB            0x15  /* Y轴加速度高字节 */
#define BMI088_ACC_Z_LSB            0x16  /* Z轴加速度低字节 */
#define BMI088_ACC_Z_MSB            0x17  /* Z轴加速度高字节 */
#define BMI088_ACC_TEMP_MSB         0x22  /* 温度高字节 */
#define BMI088_ACC_TEMP_LSB         0x23  /* 温度低字节 */
#define BMI088_FIFO_LENGTH_0        0x24  /* FIFO长度低字节 */
#define BMI088_FIFO_LENGTH_1        0x25  /* FIFO长度高字节 */
#define BMI088_FIFO_DATA            0x26  /* FIFO数据寄存器 */
#define BMI088_ACC_CONF             0x40  /* 加速度计配置 */
#define BMI088_ACC_RANGE            0x41  /* 量程配置 */
#define BMI088_FIFO_WTM_0           0x46  /* FIFO水印低字节 */
#define BMI088_FIFO_WTM_1           0x47  /* FIFO水印高字节 */
#define BMI088_FIFO_CONFIG_0        0x48  /* FIFO配置0 */
#define BMI088_FIFO_CONFIG_1        0x49  /* FIFO配置1 */
#define BMI088_ACC_INT1_IO_CONF     0x53  /* INT1引脚配置 */
#define BMI088_ACC_INT2_IO_CONF     0x54  /* INT2引脚配置 */
#define BMI088_ACC_INT1_INT2_MAP_DATA 0x58 /* 中断映射 */
#define BMI088_ACC_PWR_CONF         0x7C  /* 电源配置 */
#define BMI088_ACC_PWR_CTRL         0x7D  /* 电源控制 */
#define BMI088_ACC_SOFTRESET        0x7E  /* 软复位 */

/* 加速度计芯片ID */
#define BMI088_ACC_CHIP_ID_VALUE    0x1E

/* 加速度计配置值 */
#define BMI088_ACC_CONF_1600HZ      0xAC  /* 1600Hz, Normal滤波 */
#define BMI088_ACC_RANGE_24G        0x03  /* ±24g */
#define BMI088_ACC_PWR_ACTIVE       0x00  /* 激活模式 */
#define BMI088_ACC_PWR_ON           0x04  /* 使能加速度计 */
#define BMI088_ACC_SOFTRESET_VALUE  0xB6  /* 软复位命令 */

/* FIFO配置值 - 加速度计 */
#define BMI088_FIFO_CONFIG_0_MODE   0x02  /* Bit1=1(必须), Bit0=0(FIFO模式) */
#define BMI088_FIFO_CONFIG_1_ACC_EN 0x50  /* Bit6=1(使能加速度计), Bit4=1(必须) */
#define BMI088_INT1_OUT             0x08  /* INT1输出使能 */
#define BMI088_INT1_FWM             0x02  /* INT1映射到FIFO水印中断 */

/* FIFO帧头定义 - 加速度计 */
#define BMI088_FIFO_HEADER_ACC      0x84  /* 加速度计数据帧头 (0b10000100) */
#define BMI088_FIFO_HEADER_SKIP     0x40  /* 跳帧帧头 (0b01000000) */
#define BMI088_FIFO_HEADER_TIME     0x44  /* 时间帧头 (0b01000100) */
#define BMI088_FIFO_HEADER_CONFIG   0x48  /* 配置帧头 (0b01001000) */
#define BMI088_FIFO_HEADER_DROP     0x50  /* 丢帧帧头 (0b01010000) */
#define BMI088_FIFO_HEADER_MASK     0xFC  /* 帧头掩码（忽略INT状态位） */

/* FIFO大小定义 */
#define BMI088_FIFO_SIZE_ACCEL      1024  /* 加速度计FIFO大小（字节） */
#define BMI088_FIFO_SIZE_GYRO       600   /* 陀螺仪FIFO大小（字节，100帧×6字节） */
#define BMI088_FIFO_FRAME_SIZE_ACCEL 7    /* 加速度计帧大小（1字节header + 6字节数据） */
#define BMI088_FIFO_FRAME_SIZE_GYRO  6    /* 陀螺仪帧大小（6字节数据，无header） */

/* 数据转换系数 */
#define BMI088_ACCEL_SCALE_24G      (24.0f / 32768.0f * 9.80665f)  /* ±24g → m/s² */
#define BMI088_GYRO_SCALE_2000DPS   (2000.0f / 32768.0f * 0.017453292f)  /* ±2000dps → rad/s */
#define BMI088_TEMP_SCALE           (0.125f)  /* 温度转换系数 */
#define BMI088_TEMP_OFFSET          (23.0f)   /* 温度偏移 */

/* ========== 陀螺仪寄存器定义 ========== */
#define BMI088_GYRO_CHIP_ID         0x00  /* 芯片ID寄存器 (固定值: 0x0F) */
#define BMI088_GYRO_X_LSB           0x02  /* X轴角速度低字节 */
#define BMI088_GYRO_X_MSB           0x03  /* X轴角速度高字节 */
#define BMI088_GYRO_Y_LSB           0x04  /* Y轴角速度低字节 */
#define BMI088_GYRO_Y_MSB           0x05  /* Y轴角速度高字节 */
#define BMI088_GYRO_Z_LSB           0x06  /* Z轴角速度低字节 */
#define BMI088_GYRO_Z_MSB           0x07  /* Z轴角速度高字节 */
#define BMI088_GYRO_INT_STAT_1      0x0A  /* 中断状态1 */
#define BMI088_GYRO_RANGE           0x0F  /* 量程配置 */
#define BMI088_GYRO_BANDWIDTH       0x10  /* 带宽配置 */
#define BMI088_GYRO_LPM1            0x11  /* 低功耗模式1 */
#define BMI088_GYRO_SOFTRESET       0x14  /* 软复位 */
#define BMI088_GYRO_INT_CTRL        0x15  /* 中断控制 */
#define BMI088_GYRO_INT3_INT4_IO_CONF 0x16 /* INT3/INT4引脚配置 */
#define BMI088_GYRO_INT3_INT4_IO_MAP  0x18 /* INT3/INT4映射 */
#define BMI088_GYRO_FIFO_WM_ENABLE  0x1E  /* FIFO水印使能 */
#define BMI088_GYRO_FIFO_EXT_INT_S  0x34  /* FIFO外部中断状态 */
#define BMI088_GYRO_FIFO_STATUS     0x0E  /* FIFO状态 */
#define BMI088_GYRO_FIFO_CONFIG_0   0x3D  /* FIFO配置0 (水印) */
#define BMI088_GYRO_FIFO_CONFIG_1   0x3E  /* FIFO配置1 (模式) */
#define BMI088_GYRO_FIFO_DATA       0x3F  /* FIFO数据寄存器 */

/* 陀螺仪芯片ID */
#define BMI088_GYRO_CHIP_ID_VALUE   0x0F

/* 陀螺仪配置值 */
#define BMI088_GYRO_RANGE_2000DPS   0x00  /* ±2000 dps */
#define BMI088_GYRO_BW_2000HZ       0x00  /* 2000Hz, Normal滤波 */
#define BMI088_GYRO_NORMAL_MODE     0x00  /* 正常模式 */
#define BMI088_GYRO_SOFTRESET_VALUE 0xB6  /* 软复位命令 */

/* FIFO配置值 - 陀螺仪 */
#define BMI088_GYRO_INT_CTRL_FIFO_EN 0x40 /* FIFO中断使能 (Bit6=1) */
#define BMI088_GYRO_FIFO_WM_EN      0x88  /* FIFO水印使能 (Bit7=1, Bit3=1) */
#define BMI088_GYRO_FIFO_MODE       0x40  /* FIFO模式 (Bit6=1) */
#define BMI088_GYRO_INT3_FIFO       0x04  /* INT3映射到FIFO中断 (Bit2=1) */
#define BMI088_GYRO_INT4_FIFO       0x20  /* INT4映射到FIFO中断 (Bit5=1) */

/* ========== 数据结构定义 ========== */

/**
 * @brief BMI088原始数据结构
 */
typedef struct {
    int16_t accel_x_raw;   /* 加速度X轴原始值 */
    int16_t accel_y_raw;   /* 加速度Y轴原始值 */
    int16_t accel_z_raw;   /* 加速度Z轴原始值 */
    int16_t gyro_x_raw;    /* 陀螺仪X轴原始值 */
    int16_t gyro_y_raw;    /* 陀螺仪Y轴原始值 */
    int16_t gyro_z_raw;    /* 陀螺仪Z轴原始值 */
    int16_t temp_raw;      /* 温度原始值 */
    uint8_t accel_raw_bytes[6];  /* 加速度计原始字节数据（用于调试） */
    uint8_t temp_raw_bytes[2];   /* 温度原始字节数据（用于调试） */
} BMI088_RawData_t;

/**
 * @brief BMI088转换后数据结构
 */
typedef struct {
    float accel_x;      /* 加速度X轴 (m/s²) */
    float accel_y;      /* 加速度Y轴 (m/s²) */
    float accel_z;      /* 加速度Z轴 (m/s²) */
    float gyro_x;       /* 陀螺仪X轴 (rad/s) */
    float gyro_y;       /* 陀螺仪Y轴 (rad/s) */
    float gyro_z;       /* 陀螺仪Z轴 (rad/s) */
    float temperature;  /* 温度 (°C) */
    uint64_t timestamp; /* 时间戳 (ms) */
} BMI088_Data_t;

/**
 * @brief BMI088初始化状态
 */
typedef struct {
    uint8_t accel_initialized;  /* 加速度计初始化标志 */
    uint8_t gyro_initialized;   /* 陀螺仪初始化标志 */
    uint8_t accel_chip_id;      /* 加速度计芯片ID */
    uint8_t gyro_chip_id;       /* 陀螺仪芯片ID */
} BMI088_Status_t;

/**
 * @brief BMI088 FIFO加速度计数据帧（7字节）
 */
typedef struct __attribute__((packed)) {
    uint8_t header;      /* 帧头 (0x84) */
    uint8_t acc_x_lsb;   /* X轴低字节 */
    uint8_t acc_x_msb;   /* X轴高字节 */
    uint8_t acc_y_lsb;   /* Y轴低字节 */
    uint8_t acc_y_msb;   /* Y轴高字节 */
    uint8_t acc_z_lsb;   /* Z轴低字节 */
    uint8_t acc_z_msb;   /* Z轴高字节 */
} BMI088_FIFO_AccelFrame_t;

/**
 * @brief BMI088 FIFO陀螺仪数据帧（6字节）
 */
typedef struct __attribute__((packed)) {
    uint8_t gyro_x_lsb;  /* X轴低字节 */
    uint8_t gyro_x_msb;  /* X轴高字节 */
    uint8_t gyro_y_lsb;  /* Y轴低字节 */
    uint8_t gyro_y_msb;  /* Y轴高字节 */
    uint8_t gyro_z_lsb;  /* Z轴低字节 */
    uint8_t gyro_z_msb;  /* Z轴高字节 */
} BMI088_FIFO_GyroFrame_t;

/**
 * @brief BMI088 FIFO批量数据结构
 */
#define BMI088_FIFO_MAX_SAMPLES 32  /* 最大批量读取样本数 */

typedef struct {
    int16_t accel_x[BMI088_FIFO_MAX_SAMPLES];  /* 加速度X轴数组 */
    int16_t accel_y[BMI088_FIFO_MAX_SAMPLES];  /* 加速度Y轴数组 */
    int16_t accel_z[BMI088_FIFO_MAX_SAMPLES];  /* 加速度Z轴数组 */
    uint8_t accel_count;                        /* 加速度计样本数 */
    uint64_t accel_timestamp;                   /* 加速度计时间戳 */
} BMI088_FIFO_AccelData_t;

typedef struct {
    int16_t gyro_x[BMI088_FIFO_MAX_SAMPLES];   /* 陀螺仪X轴数组 */
    int16_t gyro_y[BMI088_FIFO_MAX_SAMPLES];   /* 陀螺仪Y轴数组 */
    int16_t gyro_z[BMI088_FIFO_MAX_SAMPLES];   /* 陀螺仪Z轴数组 */
    uint8_t gyro_count;                         /* 陀螺仪样本数 */
    uint64_t gyro_timestamp;                    /* 陀螺仪时间戳 */
} BMI088_FIFO_GyroData_t;

/* ========== 函数声明 ========== */

/**
 * @brief 初始化BMI088传感器
 * @return 0: 成功, -1: 失败
 */
int BMI088_Init(void);

/**
 * @brief 读取BMI088数据
 * @param data 数据结构指针
 * @return 0: 成功, -1: 失败
 */
int BMI088_ReadData(BMI088_Data_t *data);

/**
 * @brief 读取BMI088原始数据
 * @param raw_data 原始数据结构指针
 * @return 0: 成功, -1: 失败
 */
int BMI088_ReadRawData(BMI088_RawData_t *raw_data);

/**
 * @brief 获取BMI088初始化状态
 * @param status 状态结构指针
 */
void BMI088_GetStatus(BMI088_Status_t *status);

/**
 * @brief 读取加速度计芯片ID
 * @param chip_id 芯片ID指针
 * @return 0: 成功, -1: 失败
 */
int BMI088_ReadAccelChipID(uint8_t *chip_id);

/**
 * @brief 读取陀螺仪芯片ID
 * @param chip_id 芯片ID指针
 * @return 0: 成功, -1: 失败
 */
int BMI088_ReadGyroChipID(uint8_t *chip_id);

/**
 * @brief 初始化BMI088 FIFO模式
 * @param accel_watermark 加速度计FIFO水印（样本数，0-146）
 * @param gyro_watermark 陀螺仪FIFO水印（样本数，0-100）
 * @return 0: 成功, -1: 失败
 */
int BMI088_FIFO_Init(uint8_t accel_watermark, uint8_t gyro_watermark);

/**
 * @brief 读取加速度计FIFO数据
 * @param fifo_data FIFO数据结构指针
 * @return 读取的样本数，-1表示失败
 */
int BMI088_FIFO_ReadAccel(BMI088_FIFO_AccelData_t *fifo_data);

/**
 * @brief 读取陀螺仪FIFO数据
 * @param fifo_data FIFO数据结构指针
 * @return 读取的样本数，-1表示失败
 */
int BMI088_FIFO_ReadGyro(BMI088_FIFO_GyroData_t *fifo_data);

/**
 * @brief 复位加速度计FIFO
 * @return 0: 成功, -1: 失败
 */
int BMI088_FIFO_ResetAccel(void);

/**
 * @brief 复位陀螺仪FIFO
 * @return 0: 成功, -1: 失败
 */
int BMI088_FIFO_ResetGyro(void);

/**
 * @brief 读取加速度计FIFO长度
 * @return FIFO字节数，-1表示失败
 */
int BMI088_FIFO_GetAccelLength(void);

/**
 * @brief 读取陀螺仪FIFO状态
 * @return FIFO帧数，-1表示失败
 */
int BMI088_FIFO_GetGyroStatus(void);

/* ========== 优先级2：重要改进功能 ========== */

/**
 * @brief 寄存器配置结构 - 用于验证寄存器配置
 */
typedef struct {
    uint8_t reg;         /* 寄存器地址 */
    uint8_t set_bits;    /* 应该设置的位 */
    uint8_t clear_bits;  /* 应该清除的位 */
} BMI088_RegisterConfig_t;

/**
 * @brief 错误统计结构
 */
typedef struct {
    uint32_t accel_bad_register_count;   /* 加速度计寄存器检查失败次数 */
    uint32_t accel_bad_transfer_count;   /* 加速度计SPI传输失败次数 */
    uint32_t accel_fifo_empty_count;     /* 加速度计FIFO为空次数 */
    uint32_t accel_fifo_overflow_count;  /* 加速度计FIFO溢出次数 */
    uint32_t gyro_bad_register_count;    /* 陀螺仪寄存器检查失败次数 */
    uint32_t gyro_bad_transfer_count;    /* 陀螺仪SPI传输失败次数 */
    uint32_t gyro_fifo_empty_count;      /* 陀螺仪FIFO为空次数 */
    uint32_t gyro_fifo_overflow_count;   /* 陀螺仪FIFO溢出次数 */
} BMI088_ErrorStats_t;

/**
 * @brief 加速度计寄存器配置验证
 * @param reg_cfg 寄存器配置
 * @return 0成功，-1失败
 */
int BMI088_Accel_RegisterCheck(const BMI088_RegisterConfig_t *reg_cfg);

/**
 * @brief 陀螺仪寄存器配置验证
 * @param reg_cfg 寄存器配置
 * @return 0成功，-1失败
 */
int BMI088_Gyro_RegisterCheck(const BMI088_RegisterConfig_t *reg_cfg);

/**
 * @brief 读取加速度计温度
 * @param temperature 输出温度值（°C）
 * @return 0成功，-1失败
 */
int BMI088_Accel_UpdateTemperature(float *temperature);

/**
 * @brief 读取陀螺仪温度（BMI088陀螺仪没有温度传感器，返回加速度计温度）
 * @param temperature 输出温度值（°C）
 * @return 0成功，-1失败
 */
int BMI088_Gyro_UpdateTemperature(float *temperature);

/**
 * @brief 获取错误统计
 * @param stats 输出错误统计数据
 */
void BMI088_GetErrorStats(BMI088_ErrorStats_t *stats);

/**
 * @brief 重置错误统计
 */
void BMI088_ResetErrorStats(void);

/* ========== 优先级3：高级功能 ========== */

/* 状态机枚举 - 模仿PX4设计 */
typedef enum {
    BMI088_STATE_RESET = 0,           /* 复位状态 */
    BMI088_STATE_WAIT_FOR_RESET,      /* 等待复位完成 */
    BMI088_STATE_CONFIGURE,           /* 配置传感器 */
    BMI088_STATE_FIFO_RESET,          /* FIFO复位状态 */
    BMI088_STATE_FIFO_READ,           /* FIFO读取状态（正常运行） */
} BMI088_State_t;

/* 状态机管理函数 */
int BMI088_Reset(void);                                            /* 软复位传感器 */
BMI088_State_t BMI088_GetState(void);                              /* 获取当前状态 */
int BMI088_StateMachine(void);                                     /* 状态机处理（每次调用推进状态） */

/* FIFO管理函数 */
int BMI088_FIFO_CheckOverflow(void);                               /* 检查FIFO溢出 */
int BMI088_FIFO_ForceReset(void);                                  /* 强制复位FIFO */

/* 失败计数和自动恢复 */
void BMI088_IncrementFailureCount(void);                           /* 增加失败计数 */
void BMI088_ResetFailureCount(void);                               /* 重置失败计数 */
uint32_t BMI088_GetFailureCount(void);                             /* 获取失败计数 */

#ifdef __cplusplus
}
#endif

#endif /* __BMI088_H */

